package core.proto.rightwindow;

import java.awt.Color;
import static app.constants.CollabVizConstants.*;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.LinkedList;
import java.util.List;

import javax.activation.DataHandler;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.TransferHandler;

import core.proto.Util;
import core.proto.annotation.Annotation;

public class PopupPanel extends JScrollPane {

	private static final long serialVersionUID = 1L;
	private JPanel panel;
	private List<PostItEditor> editors;
	private BoardPane parent;

	public static final int POPUP_HEIGHT = 200;


	public PopupPanel (BoardPane parent) {
		this.parent = parent;
		editors = new LinkedList<PostItEditor>();
		panel = new JPanel(new FlowLayout() );
		panel.setBackground(Color.LIGHT_GRAY);
		this.setBorder(BorderFactory.createLineBorder(Color.black));
		this.getViewport().add(panel);
	}

	/**
	 * Side effect: panel tries to dynamically resize to fit the size of the post it. 
	 * @param postItClickedOn
	 * @param postIts
	 */
	public void addPostIts (PostIt postItClickedOn, List<PostIt> postIts) {
		panel.removeAll();
		this.editors.clear();

		// Create editing areas. 
		PostItEditor editorToScrollTo = null;
		for(PostIt pi : postIts) {
			if (pi.isLocal()) {
				PostItEditor newEditor = new PostItEditor(pi);
				this.editors.add(newEditor);
				if (pi == postItClickedOn) {
					editorToScrollTo = newEditor;
				}
				panel.add(newEditor);
			}
		}
		// This should only happen if we skipped the post it in the loop due to it not being editable. 
		if (editorToScrollTo == null && editors.size() > 0) {
			editorToScrollTo = editors.get(0);
		}
		// Try to scroll to the one we wanna edit.
		if (editorToScrollTo != null){
			this.scrollRectToVisible(editorToScrollTo.getBounds());
			editorToScrollTo.area.setEditable(true);
		}
		if (editors.size() > 0){
			PostIt pi = editors.get(0).postIt;
			int height = pi.getHeight();
			// Don't want this overlapping the chat area. 
			int width = Math.min(parent.getWidth() - parent.getChatAreaWidth(), pi.getWidth() * editors.size());
			
			int x = postItClickedOn.getX();
			if (x + width > parent.getWidth()) {
				x = parent.getWidth() - width;
			}
			
			int y = postItClickedOn.getY() + postItClickedOn.getHeight();
			if (y + postItClickedOn.getHeight() > parent.getHeight()) {
				// Put it on top instead. 
				y = postItClickedOn.getY() - postItClickedOn.getHeight();
			}
			
			this.setBounds(x, y, width, height);
		}
	}

	public void scrollRectToVisible (PostIt pi) {
		for(PostItEditor ed : this.editors) {
			if (ed.postIt == pi) {
				this.scrollRectToVisible(ed.getBounds());
				return;
			}
		}
	}

	@Override
	public void setVisible (boolean visible) {
		super.setVisible(visible);
		if (! visible) {
			for (PostItEditor ed : this.editors) {
				// Push out updates to post it. 
				if (Annotation.shouldDeleteAnnotationWith(ed.area.getText())) {
					parent.removePostIt(ed.postIt);
				}
				if (! ed.postIt.getText().equals(ed.area.getText())) {
					ed.postIt.setText(ed.area.getText());
					LeftRightCommunicator.postItUpdated(ed.postIt);
				}
			}
		}
		parent.repaint();
	}

	public class PostItEditor extends JScrollPane implements FocusListener, MouseMotionListener {

		private static final long serialVersionUID = 1L;
		public PostIt postIt;
		private JTextArea area; 

		public PostItEditor (PostIt pi) {
			this.setBorder(BorderFactory.createLineBorder(Color.black));
			this.setPreferredSize(new Dimension(200,200));
			this.setSize(200,200);
			this.postIt = pi;
			area = new JTextArea();
			area.setText(pi.getText());
			area.addFocusListener(this);
			area.setFocusable(true);
			area.setBackground(NOTE_COLOR);
			area.setWrapStyleWord(true);
			area.setLineWrap(true);
			area.setDragEnabled(true);
			area.setTransferHandler(BoardPane.getInstance().transferHandler);
			this.getViewport().add(area);
			area.addMouseMotionListener(this);
		}


		@Override
		public void focusGained(FocusEvent arg0) {
			area.setEditable(true);
			area.getCaret().setVisible(true);
		}

		@Override
		public void focusLost(FocusEvent arg0) {
			area.setEditable(false);
			area.getCaret().setVisible(false);
			postIt.setText(area.getText());
		}


		@Override
		public void mouseDragged(MouseEvent me) {
			// tell transfer handler that user is dragging this thing.
			TransferHandler th = area.getTransferHandler();
			if (th != null){
				th.exportAsDrag(this, me, TransferHandler.COPY_OR_MOVE);
			}
		}

		@Override
		public void mouseMoved(MouseEvent arg0) {
		}
	}
}